
#include "evalsoc.h"

#include "evalsoc_uart.h"
#include "test_dma.h"

#define PCLKFREQ                (50 * 1000000)
#define BAUD_RATE(n)            (PCLKFREQ / (n) / 16)
/**
 * \brief Initialize the UART.
 * @param puary:UART
 * @param baudrate:波特率
 * @param Loopback_Mode:回环模式
 * @param RCVR_Trigger:接收触发器
 * @param data_bits:数据位
 * @param stop_bits:停止位
 * @param parity:校验位
*/
int32_t uart_init( dw_uart_regs_t * puart,uint32_t baudrate,uint32_t Loopback_Mode,uint32_t RCVR_Trigger,
    data_bits_t data_bits,stop_bits_t stop_bits,parity_t parity){

    uint32_t lcr = 0;

    if (__RARELY(puart == NULL)) {
        return -1;
    }

    /* DLAB = 1  */
    puart->LCR = 0x83;
    /* Set DLL for baudrate */
    puart->DLL = BAUD_RATE(baudrate) & 0xff;
    puart->DLH = (BAUD_RATE(baudrate) >> 8) & 0xff;

    // 数据位设置（LCR[1:0]控制）
    lcr |= (data_bits - 5) & 0x03;

    // 停止位（LCR[2]控制,LCR[2]=0时为1个停止位;LCR[2]=1时，LCR[1:0]为零时为1.5个停止位，否则为2个停止位）
    if (stop_bits == STOP_BITS_2) {
        lcr |= 1 << 2;
    }else if (stop_bits == STOP_BITS_1_5){
        lcr |= 1 << 2;
        lcr &=0xfc;//当LCR[1:0]为零时，LCR[2]为1时，表示1.5个停止位
    }    

     // 奇偶校验（LCR[3:4]控制）
     if (parity != PARITY_NONE) {
        lcr |= 1 << 3; // 使能校验
        lcr |= ((parity == PARITY_EVEN) ? 1 : 0) << 4;
    }

    puart->LCR = lcr;
    
    puart->MCR = Loopback_Mode; //loopback mode

    /* IER to */
    puart->IER = 0x80;
    
    /* FCR: Enable FIFO, reset TX and RX. */
    puart->FCR =0xF|RCVR_Trigger; //enable FIFO, reset TX and RX. 
    
    return 0;
}
int32_t uart_write( dw_uart_regs_t * puart, uint8_t val )
{
    if (__RARELY(puart == NULL)) {
        return -1;
    }
    
    while ( (puart->LSR & 0x20) == 0 ) {
        __NOP();
    }
    
    /**/
    puart->THR = (uint32_t)val;
    return 0;
}


uint8_t uart_read( dw_uart_regs_t * puart )
{

    if (__RARELY(puart == NULL)) {
        return -1;
    }

    /**/
    while ( (puart->LSR & 0x1) == 0 ) {
        __NOP();
    }

    return (uint8_t)( puart->RBR );
}









